#include "blockQueue.hpp"
#include "task.hpp"

#define pcNum 2

int add(int a, int b)
{
    return a + b;
}

void *Produce(void *args)
{
    BlockQueue<Task> *bq = (BlockQueue<Task> *)args;

    while (true)
    {
        int x = rand() % 100+1;
        usleep(1000);
        int y = rand() % 100+1;
        Task ad(x, y, add);

        printf("%p produce:(%d, %d)\n", pthread_self(), ad._x, ad._y);
        bq->Push(ad);
        sleep(2);
    }
    return nullptr;
}

void *Consume(void *args)
{
    BlockQueue<Task> *bq = (BlockQueue<Task> *)args;
    while (true)
    {
        Task ad;
        bq->Pop(&ad);

        printf("%p consume, add result is %d + %d = %d\n", pthread_self(),ad._x, ad._y, ad());
        sleep(2);
    }
    return nullptr;
}

int main()
{
    srand((unsigned int)time(nullptr));

    BlockQueue<Task> *bq = new BlockQueue<Task>();

    pthread_t producter[pcNum], customer[pcNum];
    pthread_create(producter, nullptr, Produce, (void *)bq);
    pthread_create(producter + 1, nullptr, Produce, (void *)bq);
    pthread_create(customer, nullptr, Consume, (void *)bq);
    pthread_create(customer + 1, nullptr, Consume, (void *)bq);

    pthread_join(producter[0], nullptr);
    pthread_join(producter[1], nullptr);
    pthread_join(customer[0], nullptr);
    pthread_join(customer[1], nullptr);

    delete bq;

    return 0;
}